package com.prabhakar;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.servlet.http.HttpServletResponse;

import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.DuplicateRoleException;
import com.liferay.portal.NoSuchResourcePermissionException;
import com.liferay.portal.NoSuchRoleException;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.model.ResourceAction;
import com.liferay.portal.model.ResourceConstants;
import com.liferay.portal.model.ResourcePermission;
import com.liferay.portal.model.Role;
import com.liferay.portal.model.RoleConstants;
import com.liferay.portal.security.permission.ActionKeys;
import com.liferay.portal.service.ResourceActionLocalServiceUtil;
import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
import com.liferay.portal.service.RoleLocalServiceUtil;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portlet.documentlibrary.model.DLFileEntry;
import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

/**
 * author: prabhakar_singh
 */
public class UBPermsPortlet extends MVCPortlet {
 
	public void doAssignUserBasedPermission(ActionRequest actionRequest ,ActionResponse actionResponse) throws Exception{
		
		ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
		long selectedFileEntryId = ParamUtil.getLong(actionRequest, "fileSelect");
		long selectedUserId = ParamUtil.getLong(actionRequest,"userSelect");
		String selectedUserId1 = ParamUtil.getString(actionRequest,"userSelect");
		boolean viewChecked = ParamUtil.getBoolean(actionRequest, "viewCheckbox");
		Role userDefinedRole =null;
		
	//	selectedUserId = Long.parseLong(selectedUserId1);
		
		System.out.println("#### selectedUserId1 "+selectedUserId1+" $$$$ selectedUserId "+selectedUserId);
	
		if(selectedFileEntryId!=0 && selectedUserId!=0) {
			

			//Do something ... break the control --sow error msg..
			userDefinedRole = doFetchDLBasedUserRole(selectedFileEntryId, selectedUserId, themeDisplay);
			if( userDefinedRole!=null && viewChecked){
				new UBPermsPortlet().addUpdateResourcePermissions(themeDisplay,selectedFileEntryId,selectedUserId,userDefinedRole);
				
				System.out.println(" iNside add Perms --/");
			}else{
				System.out.println(" iNside remove Perms --/");
			new UBPermsPortlet().removeResourcePermissions(themeDisplay,selectedFileEntryId,selectedUserId,userDefinedRole);
			}
		}
		
		
		//throw new Exception();
	}
	

	/*	This Method is used to :-
	 *  Add/Update the Resource Permissions (used defined view/edit/delete permissions) to the Respective Roles/user_role...	
	 */
	private void addUpdateResourcePermissions(ThemeDisplay themeDisplay, long selectedFileEntryId, long selectedUserId, Role userDefinedRole) {
		
		ResourcePermission resourcePermission  = null;
		String name_DLFile = DLFileEntry.class.getName();		//DLFileEntryLocalServiceUtil.fetchDLFileEntry(selectedFileEntryId).getName();		
		String primaryKey_DLFile = StringPool.BLANK;
		long roleIdToBePermitted = (userDefinedRole!=null)?userDefinedRole.getRoleId() :0;

		
		try {
			System.out.println("selectedFileEntryId recevd in addUpdateResourcePermissions = "+selectedFileEntryId+"   selectedUserId = "+selectedUserId);
			primaryKey_DLFile = String.valueOf(DLFileEntryLocalServiceUtil.fetchDLFileEntry(selectedFileEntryId).getPrimaryKey());
			System.out.println("roleIdToBePermitted == "+roleIdToBePermitted +" name_DLFile == "+name_DLFile+" primaryKey_DLFile = "+primaryKey_DLFile);
			
			resourcePermission  = ResourcePermissionLocalServiceUtil.getResourcePermission(themeDisplay.getCompanyId(), name_DLFile, ResourceConstants.SCOPE_INDIVIDUAL, String.valueOf(primaryKey_DLFile),roleIdToBePermitted);
			//Create a Resource Action..then using for permission.
			ResourceAction resourceAction = ResourceActionLocalServiceUtil.getResourceAction(DLFileEntry.class.getName(),ActionKeys.VIEW);

			if((Validator.isNotNull(resourcePermission)&& !ResourcePermissionLocalServiceUtil.hasActionId(resourcePermission,resourceAction))){
				System.out.println(" Inside Updating Existing ResourcePermission   >>>");
				resourcePermission.setActionIds(resourcePermission.getActionIds() |resourceAction.getBitwiseValue());
				ResourcePermissionLocalServiceUtil.updateResourcePermission(resourcePermission);
			}
		}catch(NoSuchRoleException nsre){
			System.out.println("error msg4 = "+nsre.getMessage());
		}catch(NoSuchResourcePermissionException nsrpe){
			System.out.println("error msg5 = "+nsrpe.getMessage());
			try {
				resourcePermission = ResourcePermissionLocalServiceUtil.createResourcePermission(CounterLocalServiceUtil.increment(ResourcePermission.class.getName()));
				resourcePermission.setCompanyId(themeDisplay.getCompanyId());
				resourcePermission.setRoleId(roleIdToBePermitted);
				resourcePermission.setScope(ResourceConstants.SCOPE_INDIVIDUAL);
				resourcePermission.setName(name_DLFile);
				resourcePermission.setPrimKey(primaryKey_DLFile);
				System.out.println(" Inside adding new ResourcePermission   >>>");
				ResourceAction resourceAction = ResourceActionLocalServiceUtil.getResourceAction(DLFileEntry.class.getName(), ActionKeys.VIEW);
				resourcePermission.setActionIds(resourceAction.getBitwiseValue());
				ResourcePermissionLocalServiceUtil.addResourcePermission(resourcePermission);
			}catch (SystemException e) {
				e.printStackTrace();
			}catch (PortalException pe) {
				System.out.println("error msg8 = "+pe.getMessage());
				pe.printStackTrace();
			}

		} catch (SystemException e1) {
				System.out.println("error msg6 = "+e1.getMessage());
				e1.printStackTrace();
		}catch (PortalException pe) {
				System.out.println("error msg7 = "+pe.getMessage());
				pe.printStackTrace();
			}
		
	}

	
	/*	This Method is used to :-
	 *  Remove the Resource Permissions (used defined view/edit/delete permissions) to the respective Roles/user_role...	
	 */
	private void removeResourcePermissions(ThemeDisplay themeDisplay, long selectedFileEntryId,
			long selectedUserId, Role userDefinedRole) {
		
		String fileName_DLFile = DLFileEntry.class.getName();
		String primaryKey_DLFile = StringPool.BLANK;
		System.out.println("Values recevd in removeResourcePermissions : \n"+"selectedUserId > "+selectedUserId+" selectedFileEntryId = "+selectedFileEntryId+" RoleId = "+userDefinedRole.getRoleId());

		try {
			primaryKey_DLFile = String.valueOf(DLFileEntryLocalServiceUtil.fetchDLFileEntry(selectedFileEntryId).getPrimaryKey());
			ResourcePermission resourcePermission = ResourcePermissionLocalServiceUtil.getResourcePermission(themeDisplay.getCompanyId(),fileName_DLFile, ResourceConstants.SCOPE_INDIVIDUAL,primaryKey_DLFile, userDefinedRole.getRoleId());

			//Incase you wanna remove a particular Resource Permission only..(In this case View only...otherwise use removeResourcePermissions instead of removeResourcePermission)
			ResourceAction resourceAction = ResourceActionLocalServiceUtil.getResourceAction(fileName_DLFile,ActionKeys.VIEW);
			
			if(Validator.isNotNull(resourcePermission) && resourcePermission.hasActionId(resourceAction.getActionId())){
				System.out.println(" permission found ...removing permission ");	
				ResourcePermissionLocalServiceUtil.removeResourcePermission(themeDisplay.getCompanyId(),fileName_DLFile , ResourceConstants.SCOPE_INDIVIDUAL, primaryKey_DLFile, 
						userDefinedRole.getRoleId(), resourceAction.getActionId());
			}else{
				System.out.println(" No permissions found ...thus, cAN'T remove permission ");	
			}

		} catch(NoSuchResourcePermissionException nsrpe){
			System.out.println("inside NoSuchResourcePermissionException nsrpe "+nsrpe.getMessage());
		}catch (PortalException e1) {
			System.out.println("inside removeResourcePermissions e1 "+e1.getMessage());
			e1.printStackTrace();
		} catch (SystemException e2) {
			System.out.println("inside removeResourcePermissions e2 "+e2.getMessage());
			e2.printStackTrace();
		}
	}
	
	
	/*This Method :-
	* fetches the DLBasedUserRole
	*/
	private Role doFetchDLBasedUserRole(long fileEntryId , long userId ,ThemeDisplay themeDisplay){

		long selectedFileEntryId = fileEntryId;
		long selectedUserId = userId;
		String roleName = ""+selectedFileEntryId+"_"+selectedUserId+"_Role";
		int roleType = RoleConstants.TYPE_REGULAR;
		Role userDefinedRole =null;
			
			/*
			 * Create a Custom Role with the above role-name
			 */
		try {
			if(RoleLocalServiceUtil.fetchRole(themeDisplay.getCompanyId(), roleName)==null){
				userDefinedRole = RoleLocalServiceUtil.addRole(themeDisplay.getUserId(), themeDisplay.getCompanyId(), roleName, null, null, roleType);
				System.out.println(" new role created >> with roleId = > "+userDefinedRole.getRoleId());
			}else{
				userDefinedRole = RoleLocalServiceUtil.fetchRole(themeDisplay.getCompanyId(), roleName);
				System.out.println("fetched existing Role with roleID>>  userDefinedRole.getRoleId() >>> "+userDefinedRole.getRoleId());
			}

		} catch(DuplicateRoleException dre){
			System.out.println("error msg1 = "+dre.getMessage());
			dre.printStackTrace();
		}catch (PortalException e) {
			System.out.println("error msg2 = "+e.getMessage());
			e.printStackTrace();
		}catch(SystemException se){
			System.out.println("error msg3 = "+se.getMessage());
			se.printStackTrace();
		}

		return userDefinedRole;
	}
	
	
	public void doFetchRoleBasedPermissions(ActionRequest actionRequest , ActionResponse actionResponse){
		
	//	HashMap<String,String> hashMap =  new HashMap<String,String>();
		System.out.println(">>> iNSIDE doFetchRoleBasedPermissions <<<< ");
		String userPermissions = StringPool.BLANK;
		ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
		long selectedFileEntryId = ParamUtil.getLong(actionRequest, "fileSelect");
		long selectedUserId = ParamUtil.getLong(actionRequest,"userSelect");
		System.out.println(" selectedUserId = "+selectedUserId+" selectedFileEntryId = "+selectedFileEntryId);

		Role userRole = doFetchDLBasedUserRole(selectedFileEntryId, selectedUserId, themeDisplay);
		System.out.println("role fetch in doFetchRoleBasedPermissions  = "+userRole);
		List<String> actionIds = new ArrayList<String>();
		actionIds.add(ActionKeys.VIEW);
        String primaryKey = StringPool.BLANK;
        List<String > resourcePermissions = new ArrayList<String>(); 
        
         try {
        	 primaryKey = String.valueOf(DLFileEntryLocalServiceUtil.fetchDLFileEntry(selectedFileEntryId).getPrimaryKey());
			resourcePermissions = ResourcePermissionLocalServiceUtil.getAvailableResourcePermissionActionIds(themeDisplay.getCompanyId(),DLFileEntry.class.getName() ,
					ResourceConstants.SCOPE_INDIVIDUAL,primaryKey, userRole.getRoleId(), actionIds);
			
			System.out.println("resourcePermissions.size = "+resourcePermissions.size());
			for (int i=0;i<resourcePermissions.size();i++){
				String permissionValue = resourcePermissions.get(i);
				System.out.println("permissions granted  = "+permissionValue);
				userPermissions = userPermissions+permissionValue;
			}
			
		} catch (PortalException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SystemException e) {
			e.printStackTrace();
		}
         
         //return the userRole based Permissions found as a response to the AjaxCall...
         doReturnStringToAjaxCall(actionResponse, userPermissions);
         
	}
	
	private static void doReturnStringToAjaxCall(ActionResponse actionResponse , String value){
		
		PrintWriter pw ;
		HttpServletResponse httpResponse = PortalUtil.getHttpServletResponse(actionResponse);
	    try {
			pw = httpResponse.getWriter();
			pw.write(value);
			pw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
}
